repo/checkout: Cache lookups of dirmeta objects
authorColin Walters <walters@verbum.org>
Fri, 14 Apr 2017 18:00:55 +0000 (14:00 -0400)
committerAtomic Bot <atomic-devel@projectatomic.io>
Tue, 25 Apr 2017 13:40:53 +0000 (13:40 +0000)
commitb7afe91e21143d7abb0adde440683a52712aa246
tree6b4d4c2fe6afd9737dc0df30a58e74da3725c22d
parent4fc65b808a59d2e0426c7d6d469a19787bdfd7c7
repo/checkout: Cache lookups of dirmeta objects

I was reading a strace the other day and noticed we were loading the same
`.dirmeta` object many times. Unlike the other object types, `.dirmeta` objects
don't accumulate much over time; there are only so many directory metadata types.
(Without SELinux involved it'd probably be 5-6 I'd guess offhand).

For `fedora-atomic/25/x86_64/docker-host` there are currently 34 `.dirmeta` in
the tree.

But how many times during a checkout did we load those 34 dirmeta objects?
With a quick strace:

```
$ strace -s 2048 -f -o strace.log ostree --repo=repo-build checkout -U fedora-atomic/25/x86_64/docker-host host-test-checkout
$ grep dirmeta strace.log | wc -l
7165
```

After, as you'd expect, we just loaded `34` from disk.  We do
6 system calls (`openat+fstat+fstat+read+read+close`) per dirmeta,
so we dropped a total of 42780 system calls - which is about 20% of the total
system calls made.

`perf record` tells me that we're spending ~40 of our time in the kernel during
a checkout, so reducing syscall traffic helps. Though most of that appears to be
in the VFS and XFS layers for `linkat` (which isn't surprising).

So how much did perf improve? Well, on my workstation, I get a lot of
fluctuation in timing, sometimes by 30%, so this was well within the noise. But
it's well worth speeding up checkout, and I think this optimization will shine
more as we improve performance elsewhere.

Closes: #795
Approved by: jlebon
src/libostree/ostree-repo-checkout.c
src/libostree/ostree-repo-private.h
src/libostree/ostree-repo.c